//
//  main.m
//  08_IOS9新特性
//
//  Created by dllo on 16/7/13.
//  Copyright © 2016年 dllo. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Person.h"

int main(int argc, const char * argv[]) {
    
    // 1.Nullability
    Person *per = [[Person alloc] init];
    NSString *objc = nil;
    per.name = objc;
    per.name = @"张三";
    NSLog(@"%@", per.name);
    
    // null_resettable
    [per setFriends:@[@"哈哈", @"嘻嘻"]];
    [per friends];
    
    // 2.泛型
    // 带泛型的容器(规定了容器中所存储的类型)
    // 声明一个可变数组,内部存放的都是NSString
    // 1.数组中添加其他类型会有警告
    // 2.数组取出来的类型不再是id类型,对应变成声明时的类型
    // 3.泛型会改变类的一些方法,使与声明的类型相同
    
    // 带泛型的数组
    NSMutableArray<NSString *> *array = [NSMutableArray arrayWithObjects:@"123", nil];
//    [array.firstObject length];
    NSUInteger len = array.firstObject.length;
    NSLog(@"%ld", len);
//    [array addObject:@20];
//    [array addObject:per];
    
    // 带泛型的字典
    // 凡是签了NSCopying协议的都可以作为key
    NSMutableDictionary<NSString *, NSString *> *dic = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"yuhan", @"name", nil];
    NSUInteger len1 = [dic objectForKey:@"name"].length;
    
    // 自定义泛型声明方式:
    /*
     @interface 类名<泛型名>: 父类
     自定义泛型,声明后,泛型名,可以应用在属性,方法中
     泛型名 等效于 类型修饰(例: NSString *)
     */
    
    // 协变性: 子类在给父类赋值时自动强转,常用  
    // 逆变性: 父类在给子类赋值时自动强转
    
    // 类的返回值加__kindof修饰后, 返回这个类及其子类的类型
    
    return 0;
}
